﻿using Cyss.Core.Helper;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Cyss.TaskManager.Infrastructure
{
    /// <summary>
    ///     任务接口
    /// </summary>
    public abstract class IService
    {


        public IService()
        {
            this.ServiceName = "服务名称";
            this.Interval = 60 * 5;
            this.logFileName = this.GetType().Name;
        }

        #region 成员

        public int TaskId { set; get; }

        /// <summary>
        /// log文件名称
        /// </summary>
        public string logFileName { set; get; }

        /// <summary>
        /// 服务名称
        /// </summary>
        public string ServiceName { set; get; }

        /// <summary>
        ///任务执行时间间隔
        /// </summary>
        public int Interval { set; get; }

        /// <summary>
        /// 显示顺序
        /// </summary>
        public int DisplayOrder { set; get; }

        #region 验证程序是否执行完逻辑
        /// <summary>
        /// 记录正在运行任务对接
        /// </summary>
        private int _TaskCount = 0;

        /// <summary>
        /// 
        /// </summary>
        private object objlock = new object();

        /// <summary>
        /// 正在执行的任务数
        /// </summary>
        protected int TaskCount { get { return _TaskCount; } }

        /// <summary>
        /// 是否正在执行中
        /// </summary>
        public bool IsTaskExecuting
        {
            get
            {
                return _TaskCount > 0 ? true : false;
            }
        }

        /// <summary>
        /// 添加任务计数
        /// </summary>
        /// <param name="state"></param>
        protected void AddTaskExecuting()
        {
            lock (objlock)
            {
                _TaskCount += 1;
            }
        }
        /// <summary>
        ///减少任务计数
        /// </summary>
        /// <param name="state"></param>
        protected void RemoveTaskExecuting()
        {
            lock (objlock)
            {
                _TaskCount -= 1;
            }
        }
        #endregion

        /// <summary>
        /// 添加子任务
        /// </summary>
        /// <param name="callBack"></param>
        /// <param name="state"></param>
        protected void CreateChildTask(WaitCallback calback, object state)
        {
            AddTaskExecuting();
            ChildTaskState taskstate = new ChildTaskState();
            taskstate.Calback = calback;
            taskstate.State = state;
            ThreadPool.QueueUserWorkItem(CallBack, taskstate);

        }
        private void CallBack(object state)
        {
            ChildTaskState taskstate = state as ChildTaskState;
            try
            {
                taskstate.Calback(taskstate.State);
            }
            catch (Exception ex)
            {
                InsertLog("子任务执行异常:" + ex.Message);
                LogHelper.WriteTextLog(ex.ToString(), "CallBack", this.ServiceName);
            }

            RemoveTaskExecuting();
        }

        /// <summary>
        /// 开始任务
        /// </summary>
        public async Task<bool> Start(object state)
        {
            bool IsSuccess = false;
            InsertLog("开始执行任务");
            AddTaskExecuting();
            try
            {
                IsSuccess = Execute(state);
                IsSuccess = await ExecuteAsync(state);
            }
            catch (Exception ex)
            {
                IsSuccess = false;
                InsertLog("执行任务异常:" + ex.Message);
                LogHelper.WriteTextLog(ex.ToString(), "Execute", this.ServiceName);
            }
            Thread.Sleep(1000);
            ///等待所有的子任务执行完成
            while (TaskCount > 1)
            {
                Thread.Sleep(100);
            }
            RemoveTaskExecuting();
            InsertLog("结束执行任务");
            return IsSuccess;
        }

        /// <summary>
        ///包含异步任务业务逻辑
        /// </summary>
        protected virtual Task<bool> ExecuteAsync(object state)
        {
            return Task.FromResult(true);
        }

        /// <summary>
        ///任务业务逻辑
        /// </summary>
        protected virtual bool Execute(object state)
        {
            return true;
        }

        /// <summary>
        /// 添加日志
        /// </summary>
        protected virtual void InsertLog(string content, string type = "")
        {
            LoggingManager.Insert(new Models.TaskLogging { TaskId = this.TaskId, Type = type, Content = content, CreateTime = DateTime.Now });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Msg"></param>
        /// <param name="action"></param>
        public void WriteTextAndUI(string Msg, string action = "")
        {
            InsertLog(Msg);
            LogHelper.WriteTextLog(Msg, action, logFileName);
        }

        private class ChildTaskState
        {
            public WaitCallback Calback { set; get; }

            public object State { set; get; }
        }
        #endregion
    }
}
